package org.nuonuo.sdk.constant;

import javax.validation.ValidationException;


/**
 * <pre>
 * 发票状态：
 *  一、回调发票状态：
 *   1 开票完成
 *   2 开票失败
 *   3 开票成功签章失败（电票时）
 *  二、查询发票状态：
 *   2 开票完成（最终状态）
 *   20 开票中
 *   21 开票成功签章中
 *   22 开票失败
 *   24 开票成功签章失败
 *   3 发票已作废
 *   31 发票作废中
 *  三、业务系统综合发票状态（最终状态）：
 *   -1 未知状态
 *   0 发票待开
 *   1 开票中
 *   2 开票完成
 *   3 开票失败
 *   4 红票申请中
 *   5 红冲中
 *   6 已红冲
 *   7 作废中
 *   8 已作废
 *   9 开票成功签章中
 *   10 开票成功签章失败
 * </pre>
 *
 * @Version 1.0
 * @Author az
 * @Date 2024-05-17 10:31:51
 * @ClassName InvoiceStatus
 * @Description 发票状态
 */
public interface InvoiceConstant {

    /**
     * <pre>
     *     1 开票完成
     * </pre>
     */
    String IC1 = "1";

    /**
     * <pre>
     *     2 开票失败
     *     2 开票完成（最终状态）
     * </pre>
     */
    String IC2 = "2";

    /**
     * <pre>
     *     3 开票成功签章失败（电票时）
     *     3 发票已作废
     * </pre>
     */
    String IC3 = "3";

    /**
     * <pre>
     *     20 开票中
     * </pre>
     */
    String IC20 = "20";

    /**
     * <pre>
     *    21 开票成功签章中
     * </pre>
     */
    String IC21 = "21";

    /**
     * <pre>
     *     22 开票失败
     * </pre>
     */
    String IC22 = "22";

    /**
     * <pre>
     *     24 开票成功签章失败
     * </pre>
     */
    String IC24 = "24";

    /**
     * <pre>
     *     31 发票作废中
     * </pre>
     */
    String IC31 = "31";

    /**
     * <pre>
     * 转换查询发票状态：
     *   2 开票完成（最终状态）
     *   20 开票中
     *   21 开票成功签章中
     *   22 开票失败
     *   24 开票成功签章失败
     *   3 发票已作废
     *   31 发票作废中
     *  为业务系统综合发票状态（最终状态）：
     *   -1 未知状态
     *   0 发票待开
     *   1 开票中
     *   2 开票完成
     *   3 开票失败
     *   4 红票申请中
     *   5 红冲中
     *   6 已红冲
     *   7 作废中
     *   8 已作废
     *   9 开票成功签章中
     *   10 开票成功签章失败
     * </pre>
     * @param status
     * @return
     */
    static InvoiceStatus apiInvoiceStatusParse(String status) {
        InvoiceStatus invoiceStatus;
        switch (status) {
            case IC2:
                invoiceStatus = InvoiceStatus.IS2;
                break;
            case IC3:
                invoiceStatus = InvoiceStatus.IS8;
                break;
            case IC20:
                invoiceStatus = InvoiceStatus.IS1;
                break;
            case IC21:
                invoiceStatus = InvoiceStatus.IS9;
                break;
            case IC22:
                invoiceStatus = InvoiceStatus.IS3;
                break;
            case IC24:
                invoiceStatus = InvoiceStatus.IS10;
                break;
            case IC31:
                invoiceStatus = InvoiceStatus.IS7;
                break;
            default:
                invoiceStatus = InvoiceStatus.UNKONW;
        }
        return invoiceStatus;
    }

    /**
     * <pre>
     * 转换回调发票状态：
     *   1 开票完成
     *   2 开票失败
     *   3 开票成功签章失败（电票时）
     *  为业务系统综合发票状态（最终状态）：
     *   -1 未知状态
     *   0 发票待开
     *   1 开票中
     *   2 开票完成
     *   3 开票失败
     *   4 红票申请中
     *   5 红冲中
     *   6 已红冲
     *   7 作废中
     *   8 已作废
     *   9 开票成功签章中
     *   10 开票成功签章失败
     * </pre>
     * @param status
     * @return
     */
    static InvoiceStatus callbackInvoiceStatusParse(String status) {
        InvoiceStatus invoiceStatus;
        switch (status) {
            case IC1:
                invoiceStatus = InvoiceStatus.IS2;
                break;
            case IC2:
                invoiceStatus = InvoiceStatus.IS3;
                break;
            case IC3:
                invoiceStatus = InvoiceStatus.IS10;
                break;
            default:
                invoiceStatus = InvoiceStatus.UNKONW;
        }
        return invoiceStatus;
    }

    /**
     * <pre>
     * 可开票状态:
     *  0 发票待开
     *  3 开票失败
     *  5 已红冲
     *  7 已作废
     *  9 开票成功签章失败
     * </pre>
     * @param status
     */
    static void abledIssue(Integer status) {
        abledIssue(InvoiceStatus.getStatus(status));
    }

    /**
     * <pre>
     * 可开票状态:
     *  0 发票待开
     *  3 开票失败
     *  6 已红冲
     *  8 已作废
     *  10 开票成功签章失败
     * </pre>
     * @param status
     */
    static void abledIssue(InvoiceStatus status) {
        switch (status) {
            case IS0:
            case IS3:
            case IS6:
            case IS8:
            case IS10:
                break;
            default:
                throw new ValidationException(status.label);
        }
    }

    /**
     * <pre>
     * 可申请红冲状态:
     *  2 开票完成
     * </pre>
     * @param status
     */
    static void abledApplayRed(Integer status) {
        abledApplayRed(InvoiceStatus.getStatus(status));
    }

    /**
     * <pre>
     * 可申请红冲状态:
     *  2 开票完成
     * </pre>
     * @param status
     */
    static void abledApplayRed(InvoiceStatus status) {
        switch (status) {
            case IS2:
                break;
            default:
                throw new ValidationException(status.label);
        }
    }

    /**
     * <pre>
     * 可确认红冲状态:
     *  4 红票申请中
     * </pre>
     * @param status
     */
    static void abledIssueRed(Integer status) {
        abledIssueRed(InvoiceStatus.getStatus(status));
    }

    /**
     * <pre>
     * 可确认红冲状态:
     *  4 红票申请中
     * </pre>
     * @param status
     */
    static void abledIssueRed(InvoiceStatus status) {
        switch (status) {
            case IS4:
                break;
            default:
                throw new ValidationException(status.label);
        }
    }

    /**
     * <pre>
     * 可重复开票:
     *  1 开票中
     * </pre>
     * @param status
     */
    static void abledReIssue(Integer status) {
        abledReIssue(InvoiceStatus.getStatus(status));
    }

    /**
     * <pre>
     * 可重复开票:
     *  1 开票中
     * </pre>
     * @param status
     */
    static void abledReIssue(InvoiceStatus status) {
        switch (status) {
            case IS1:
                break;
            default:
                throw new ValidationException(status.label+"不可重复开票");
        }
    }

    /**
     * 需要重新查询
     * @param status
     * @return
     */
    static boolean needQuery(Integer status) {
        InvoiceStatus invoiceStatus = InvoiceStatus.getStatus(status);
        boolean sender;
        switch (invoiceStatus) {
            case IS1:
            case IS9:
            case IS7:
                sender = true;
                break;
            default:
                sender = false;
        }
        return sender;
    }

    
    enum InvoiceStatus {
        /** -1 未知状态 */
        UNKONW(-1, "未知状态"),
        /** 0 发票待开 */
        IS0(0, "发票待开"),
        /** 1 开票中 */
        IS1(1, "开票中"),
        /** 2 开票完成 */
        IS2(2, "开票完成"),
        /** 3 开票失败 */
        IS3(3, "开票失败"),
        /** 4 红票申请中 */
        IS4(4, "红票申请中"),
        /** 5 红冲中 */
        IS5(5, "红冲中"),
        /** 6 已红冲 */
        IS6(6, "已红冲"),
        /** 7 作废中 */
        IS7(7, "作废中"),
        /** 8 已作废 */
        IS8(8, "已作废"),
        /** 9 开票成功签章中 */
        IS9(9, "开票成功签章中"),
        /** 9 开票成功签章失败 */
        IS10(10, "开票成功签章失败"),
        ;
        private final Integer value;
        private final String label;

        InvoiceStatus(Integer value, String label) {
            this.value = value;
            this.label = label;
        }

        public Integer getValue() {
            return value;
        }

        public String getLabel() {
            return label;
        }


        static InvoiceStatus getStatus(Integer value) {
            if (value == null) return InvoiceStatus.UNKONW;
            InvoiceStatus[] values = InvoiceStatus.values();

            for (int i = 0, j = values.length; i<j; i++) {
                InvoiceStatus status = values[i];
                if (status.getValue().equals(value)) return status;
            }
            return InvoiceStatus.UNKONW;
        }
    }

}
